/** @file
This Library is mainly used to some function about bmc.

Copyright (C) 2023, Phytium Technology Co., Ltd. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/ParameterTable.h>

#define  PHYTIUM_PAD_REGISTER_BASE     (0x38003000)
#define  PHYTIUM_KCS_CLK_KCS_RSTN_O    (0x0FFFFF9C)
#define  PHYTIUM_KCS_NU_SERIRQ_CONFIG  (0x0FFFFFB8)

#define  PAD_FUNC_ENABLE       (0x4)
#define  PAD_DRIVER0           (0x10)
#define  PAD_STATUS_JTAGNSW    (0x15C)
#define  PAD_CRU_CKOBV_SEL0    (0x160)
#define  PAD_CLK_KCS_O         (0x1D8)
#define  PAD_KCS_EXT_RSTN_O    (0x1DC)
#define  PAD_KCS_LDRQ_N        (0x1E0)
#define  PAD_KCS_EXT_LFRAME_N  (0x1E4)
#define  PAD_EXT_KCS_IRQ_N     (0x1E8)
#define  PAD_EXT_KCS_LAD0      (0x1EC)
#define  PAD_EXT_KCS_LAD1      (0x1F0)
#define  PAD_EXT_KCS_LAD2      (0x1F4)
#define  PAD_EXT_KCS_LAD3      (0x1F8)


/**
  Check BMC in place or not.

  @retval  EFI_SUCCESS    BMC is in place.
  @retval  EFI_NOT_FOUND  BMC is not in place.

**/
EFI_STATUS
EFIAPI
CheckBmcInPlace (
  VOID
  )
{
  EFI_STATUS                 Status;
  PARAMETER_BOARD_CONFIG_V2  *BoardConfig;
  UINT8                      Buffer[256];

  ZeroMem (Buffer, 256);
  Status = EFI_NOT_FOUND;
  if (EFI_SUCCESS == GetParameterInfo (PM_BOARD_V2, Buffer, 256)) {
    BoardConfig = (PARAMETER_BOARD_CONFIG_V2 *) Buffer;
    PrintBoardParameter (PM_BOARD_V2, Buffer);
    if (BoardConfig->BmcEnable != 0) {
      //in place read from parameter
      DEBUG ((DEBUG_INFO, "BMC is in place!\n"));
      Status = EFI_SUCCESS;
    } else {
      //not in place read from parameter table
      DEBUG ((DEBUG_INFO, "BMC is not in place!\n"));
      Status = EFI_NOT_FOUND;
    }
  } else {
    //If the board information of parameter table is not existed,
    //it means bmc is not in place.
    DEBUG ((DEBUG_ERROR, "Get Board Parameter Fail.\n"));
    DEBUG ((DEBUG_INFO, "Bmc is not in place!\n"));
    Status  = EFI_NOT_FOUND;
  }

  return Status;
}

/**
  Initialized the Kcs Interface.

**/
VOID
KcsInit (
  VOID
  )
{
  DEBUG((DEBUG_INFO,"Platform Kcs Init \n"));

  MmioWrite32 (PHYTIUM_PAD_REGISTER_BASE + PAD_FUNC_ENABLE, 0x2);
  MmioWrite32 (PHYTIUM_PAD_REGISTER_BASE + PAD_DRIVER0, 0x200);
  MmioWrite32 (PHYTIUM_PAD_REGISTER_BASE + PAD_STATUS_JTAGNSW, 0x2);
  MmioWrite32 (PHYTIUM_PAD_REGISTER_BASE + PAD_CRU_CKOBV_SEL0, 0x2);
  MmioWrite32 (PHYTIUM_PAD_REGISTER_BASE + PAD_CLK_KCS_O, 0x0);
  MmioWrite32 (PHYTIUM_PAD_REGISTER_BASE + PAD_KCS_EXT_RSTN_O, 0x0);
  MmioWrite32 (PHYTIUM_PAD_REGISTER_BASE + PAD_KCS_LDRQ_N, 0x0);
  MmioWrite32 (PHYTIUM_PAD_REGISTER_BASE + PAD_KCS_EXT_LFRAME_N, 0x0);
  MmioWrite32 (PHYTIUM_PAD_REGISTER_BASE + PAD_EXT_KCS_IRQ_N, 0x0);
  MmioWrite32 (PHYTIUM_PAD_REGISTER_BASE + PAD_EXT_KCS_LAD0, 0x0);
  MmioWrite32 (PHYTIUM_PAD_REGISTER_BASE + PAD_EXT_KCS_LAD1, 0x0);
  MmioWrite32 (PHYTIUM_PAD_REGISTER_BASE + PAD_EXT_KCS_LAD2, 0x0);
  MmioWrite32 (PHYTIUM_PAD_REGISTER_BASE + PAD_EXT_KCS_LAD3, 0x0);

  MmioWrite32 (PHYTIUM_KCS_CLK_KCS_RSTN_O, 0x01);
  MmioWrite32 (PHYTIUM_KCS_NU_SERIRQ_CONFIG, 0x2);
}
